package ddz.logic.game;

import ch.qos.logback.classic.Logger;
import com.kaka.notice.annotation.Handler;
import ddz.constants.Crypto;
import ddz.constants.ErrCode;
import ddz.constants.ErrLevel;
import ddz.constants.OpCode;
import ddz.core.*;
import ddz.db.dao.TableDao;
import ddz.db.dao.UserDao;
import ddz.db.entity.UserInfo;
import ddz.net.LogicDataHandler;
import ddz.net.ProtocolMessage;
import ddz.protos.Game;
import ddz.protos.GameMipai;
import org.slf4j.LoggerFactory;

/**
 * 明牌
 *
 * @author zkpursuit
 */
@Handler(cmd = OpCode.cmd_mingpai, type = String.class)
public class MingPaiHandler extends LogicDataHandler {

    private static final Logger logger = (Logger) LoggerFactory.getLogger(MingPaiHandler.class);

    @Override
    public void execute(ProtocolMessage msg) throws Exception {
        GameMipai.CsMing reqData = (GameMipai.CsMing) msg.getBody();
        UserDao userDao = this.retrieveProxy(UserDao.class);
        UserInfo userInfo = userDao.getUserInfo(msg.uid());
        if (userInfo == null) {
            logger.info("玩家 [{}] 数据不存在", msg.uid());
            sendError(msg.ctx(), opcode(), ErrLevel.ERROR, ErrCode.data_err);
            return;
        }
        long deskId = userInfo.getDeskId();
        if (deskId <= 0) {
            logger.error("玩家（" + msg.uid() + "）未加入任何房间");
            sendError(msg.ctx(), opcode(), ErrLevel.ERROR, ErrCode.no_join_room);
            return;
        }
        TableDao tableDao = this.retrieveProxy(TableDao.class);
        Table table = tableDao.getDesk(deskId);
        if (table == null) {
            logger.error("玩家（" + msg.uid() + "）未加入任何房间");
            sendError(msg.ctx(), opcode(), ErrLevel.ERROR, ErrCode.no_join_room);
            return;
        }
        if (table.getState() != TableState.fa_pai) {
            logger.error("玩家 [{}] 所在房间 [{}] 非发牌阶段", msg.uid(), table.getId());
            sendError(msg.ctx(), opcode(), ErrLevel.ERROR, ErrCode.no_join_room);
            return;
        }
        Player player = table.getPlayerByUid(msg.uid());
        if (player == null) {
            logger.error("玩家 [{}：{}] 在 [{}] 房间中无对应的数据", player.getSeatIndex(), msg.uid(), table.getId());
            sendError(msg.ctx(), opcode(), ErrLevel.ERROR, ErrCode.data_err);
            return;
        }
        if (table.isAlreadyMingPai(player.getSeatIndex())) {
            logger.error("玩家 [{}：{}] 在 [{}] 中已进行明牌操作", player.getSeatIndex(), msg.uid(), table.getId());
            sendError(msg.ctx(), opcode(), ErrLevel.WARN, ErrCode.illegal_operation);
            return;
        }
        table.addOptRecord(new OptRecord(OptType.mingpai, player.getSeatIndex()));
        tableDao.insertOrUpdateDesk(table);
        int[] beis = table.getMultiple();
        int[] cards = player.getMycards().getCards();
        Game.Cards.Builder cardsBuilder = Game.Cards.newBuilder();
        for (int i = 0; i < cards.length; i++) {
            cardsBuilder.addCard(cards[i]);
        }

        Player[] players = table.getPlayers();
        for (Player member : players) {
            GameMipai.ScMing.Builder builder = GameMipai.ScMing.newBuilder()
                    .setSeat(player.getSeatIndex())
                    .setBei(beis[player.getSeatIndex()]);
            builder.setCards(cardsBuilder.build());
            this.sendData(member.getUid(), Crypto.isCrypto, opcode(), builder.build().toByteArray());
        }
    }
}
